package com.eleventwelve.iris.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.opentides.bean.FileInfo;
import org.opentides.service.FileInfoService;
import org.opentides.util.DateUtil;
import org.opentides.util.FileUtil;
import org.opentides.util.StringUtil;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.eleventwelve.iris.entity.Patient;
import com.eleventwelve.iris.service.PatientService;
import com.eleventwelve.iris.utilities.ScannedFileContainer;

@SuppressWarnings("deprecation")
public class PatientFileFormController extends SimpleFormController{
	
	private FileInfoService fileInfoService;
	
	private PatientService patientService;
	
	private String uploadPath = (new StringBuilder()).append(File.separator)
			.append("patient_files").toString();

	private boolean multipleUpload = true;
	
	
	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		Patient patient = new Patient();
		
		String patientId = request.getParameter("patientId");
		if(!StringUtil.isEmpty(patientId) && StringUtils.isNumeric(patientId)){
			patient = patientService.load(patientId);
		}
		
		return patient;
	}
	
	@Override
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
	}
	
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		
		Patient patient = (Patient) command;
		
		processUpload(request, response, command, errors, patient.getTempFile());

		patientService.save(patient);
		
		return new ModelAndView("redirect:/patient/file/upload.jspx?patientId="+patient.getId()+"&action=upload", "file", patient.getTempFile());
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
	protected FileInfo processUpload(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors, MultipartFile multipartFile) throws IOException {

		FileInfoService fileInfoService = (FileInfoService) this.fileInfoService;
		if (ScannedFileContainer.class.isAssignableFrom(command.getClass())
				&& (request instanceof MultipartHttpServletRequest)) {
			ScannedFileContainer container = (ScannedFileContainer) command;
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			
			if (multipartFile != null && !multipartFile.isEmpty()) {

					FileInfo fileInfo = new FileInfo();
					fileInfo.setFilename(multipartFile.getOriginalFilename());
					fileInfo.setFileSize(Long.valueOf(multipartFile.getSize()));
					fileInfo.setFullPath(uploadPath);

					try {
						File directory = FileUtil.createDirectory(uploadPath);
						String subdir = (new StringBuilder())
								.append(directory.getAbsoluteFile())
								.append(File.separator)
								.append(DateUtil.convertShortDate(new Date()))
								.toString();
						File subDirectory = FileUtil.createDirectory(subdir);
						String filePath = (new StringBuilder())
								.append(subDirectory.getAbsoluteFile())
								.append(File.separator)
								.append(multipartFile.getOriginalFilename())
								.toString();
						if (fileInfoService.getFileInfoByFullPath(filePath) != null) {
							Long fileCnt = Long.valueOf(1L);
							String newFilePath;
							for (newFilePath = (new StringBuilder())
									.append(subDirectory.getAbsoluteFile())
									.append(File.separator)
									.append(fileCnt.toString())
									.append("_")
									.append(multipartFile.getOriginalFilename())
									.toString(); fileInfoService
									.getFileInfoByFullPath(newFilePath) != null; newFilePath = (new StringBuilder())
									.append(subDirectory.getAbsoluteFile())
									.append(File.separator)
									.append(fileCnt.toString())
									.append("_")
									.append(multipartFile.getOriginalFilename())
									.toString()) {
								Long long1 = fileCnt;
								Long long2 = fileCnt = Long.valueOf(fileCnt
										.longValue() + 1L);
								Long _tmp = long1;
							}

							filePath = newFilePath;
							fileInfo.setOriginalFileName(multipartFile
									.getOriginalFilename());
						}
	
						File uploadFile = new File(filePath);
						fileInfo.setFullPath(uploadFile.getAbsolutePath());
						FileUtil.copyMultipartFile(multipartFile, uploadFile);
						List files = null;
						if (multipleUpload)
							files = container.getScannedFiles();
						if (files == null)
							files = new ArrayList();
						files.add(fileInfo);
						container.setScannedFiles(files);
						return fileInfo;
						
					} catch (IOException e) {
						throw e;
					}
			}
			
		}
		return null;
	}

	public FileInfoService getFileInfoService() {
		return fileInfoService;
	}

	public void setFileInfoService(FileInfoService fileInfoService) {
		this.fileInfoService = fileInfoService;
	}

	public PatientService getPatientService() {
		return patientService;
	}

	public void setPatientService(PatientService patientService) {
		this.patientService = patientService;
	}

	public String getUploadPath() {
		return uploadPath;
	}

	public void setUploadPath(String uploadPath) {
		this.uploadPath = uploadPath;
	}

	public boolean isMultipleUpload() {
		return multipleUpload;
	}

	public void setMultipleUpload(boolean multipleUpload) {
		this.multipleUpload = multipleUpload;
	}
	
	

}
